home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / gconio.exe / GCONIO.CPP < prev    next >
C/C++ Source or Header  |  1991-03-30  |  14KB  |  562 lines

  1. /*
  2.  
  3.     gconio.cpp
  4.     3-30-91
  5.     graphics console class for Borland C++
  6.  
  7.     Copyright 1991
  8.     John W. Small
  9.     All rights reserved
  10.     Use freely but acknowledge authorship and copyright.
  11.     CIS: 73757,2233
  12.  
  13.     PSW / Power SoftWare
  14.     P.O. Box 10072
  15.     McLean, Virginia 22102 8072
  16.     (703) 759-3838
  17.  
  18. */
  19.  
  20. #include <gconio.hpp>
  21. #include <stdio.h>
  22. #include <stdarg.h>
  23. #include <dos.h>
  24.  
  25. GraphicsConsole::GraphicsConsole()
  26. {
  27.     ColumnLeft = 0;
  28.     InputWriteMode = COPY_PUT;
  29.     InputRewrite = 0;
  30.     InputDone = 0;
  31.     OutputWriteMode = COPY_PUT;
  32.     ClearTextBk = 0;
  33.     TextBkPattern = SOLID_FILL;
  34.     TextBkColor = 0; // 0 = current bkcolor
  35.     CursorChar[0] = '\124'; // 0 = no getch/gets cursor
  36.     CursorChar[1] = '\0';
  37.     CursorOnMsec = 100;
  38.     CursorOffMsec = 100;
  39. }
  40.  
  41. void GraphicsConsole::ProportionalBackSpace(int& lastchX,
  42.     int& lastchY, int chX, int chY, char lastch,
  43.     char ch, struct textsettingstype& TS)
  44. {
  45.     char lastchs[2];
  46.     char chs[2];
  47.     struct textsettingstype tmpTS;
  48.  
  49.     lastchX = chX;
  50.     lastchY = chY;
  51.     lastchs[0] = lastch;
  52.     lastchs[1] = '\0';
  53.     chs[0] = ch;
  54.     chs[1] = '\0';
  55.     gettextsettings(&tmpTS);
  56.     settextstyle(TS.font,TS.direction,TS.charsize);
  57.     if (TS.direction == HORIZ_DIR)
  58.     switch  (TS.horiz)  {
  59.     case LEFT_TEXT:
  60.         lastchX -= textwidth(lastchs);
  61.         break;
  62.     case CENTER_TEXT:
  63.         lastchX -= (textwidth(chs) >> 1);
  64.         lastchX -= (textwidth(lastchs) >> 1);
  65.         break;
  66.     case RIGHT_TEXT:
  67.         lastchX -= textwidth(chs);
  68.         break;
  69.     }
  70.     else
  71.     switch (TS.vert)  {
  72.     case BOTTOM_TEXT:
  73.         lastchY += textwidth(lastchs);
  74.         break;
  75.     case CENTER_TEXT:
  76.         lastchY += (textwidth(chs) >> 1);
  77.         lastchY += (textwidth(lastchs) >> 1);
  78.         break;
  79.     case TOP_TEXT:
  80.         lastchY += textwidth(chs);
  81.         break;
  82.     }
  83.     settextstyle(tmpTS.font,tmpTS.direction,tmpTS.charsize);
  84. }
  85.  
  86. void GraphicsConsole::ProportionalSpace(int chX, int chY,
  87.     int& nextchX, int& nextchY, char ch, char nextch,
  88.     struct textsettingstype& TS)
  89. {
  90.     char chs[2];
  91.     char nextchs[2];
  92.     struct textsettingstype tmpTS;
  93.  
  94.     nextchX = chX;
  95.     nextchY = chY;
  96.     chs[0] = ch;
  97.     chs[1] = '\0';
  98.     nextchs[0] = nextch;
  99.     nextchs[1] = '\0';
  100.     gettextsettings(&tmpTS);
  101.     settextstyle(TS.font,TS.direction,TS.charsize);
  102.     if (TS.direction == HORIZ_DIR)
  103.     switch (TS.horiz)  {
  104.     case LEFT_TEXT:
  105.         nextchX += textwidth(chs);
  106.         break;
  107.     case CENTER_TEXT:
  108.         nextchX += (textwidth(chs) >> 1);
  109.         nextchX += (textwidth(nextchs) >> 1);
  110.         break;
  111.     case RIGHT_TEXT:
  112.         nextchX += textwidth(nextchs);
  113.         break;
  114.     }
  115.     else
  116.     switch (TS.vert)  {
  117.     case BOTTOM_TEXT:
  118.         nextchY -= textwidth(chs);
  119.         break;
  120.     case CENTER_TEXT:
  121.         nextchY -= (textwidth(chs) >> 1);
  122.         nextchY -= (textwidth(nextchs) >> 1);
  123.         break;
  124.     case TOP_TEXT:
  125.         nextchY -= textwidth(nextchs);
  126.         break;
  127.     }
  128.     settextstyle(tmpTS.font,tmpTS.direction,tmpTS.charsize);
  129. }
  130.  
  131. void GraphicsConsole::TextBox(int x, int y, char *s,
  132.     struct textsettingstype& TS,
  133.     int& x1, int& y1, int& x2, int& y2)
  134. {
  135.     int dx, dy;
  136.     struct textsettingstype tmpTS;
  137.  
  138.     gettextsettings(&tmpTS);
  139.     settextstyle(TS.font,TS.direction,TS.charsize);
  140.     if (TS.direction == HORIZ_DIR)  {
  141.     dx = textwidth(s);
  142.     dy = textheight(s);
  143.     // Stroked fonts have long decenders!
  144.     if (TS.font != DEFAULT_FONT)
  145.         y += (dy >> 2);
  146.     }
  147.     else  {
  148.     dx = textheight(s);
  149.     dy = textwidth(s);
  150.     // Stroked fonts have long decenders!
  151.     if (TS.font != DEFAULT_FONT)  {
  152.         x += (dx >> 2);
  153.         // Correct quirk in outtext[xy]
  154.         if (TS.horiz == CENTER_TEXT)
  155.         if ((dx % 2) != 0)
  156.             x += 2;
  157.         else
  158.             x++;
  159.         }
  160.     }
  161.     settextstyle(tmpTS.font,tmpTS.direction,tmpTS.charsize);
  162.     x1 = x; x2 = x1;
  163.     y1 = y; y2 = y1;
  164.     switch (TS.horiz)  {
  165.     case LEFT_TEXT:
  166.     x2 += dx;
  167.     break;
  168.     case CENTER_TEXT:
  169.     x1 -= (dx >> 1);
  170.     x2 += (dx >> 1);
  171.     break;
  172.     case RIGHT_TEXT:
  173.     x1 -= dx;
  174.     break;
  175.     }
  176.     switch (TS.vert)  {
  177.     case BOTTOM_TEXT:
  178.     y1 -= dy;
  179.     break;
  180.     case CENTER_TEXT:
  181.     y1 -= (dy >> 1);
  182.     y2 += (dy >> 1);
  183.     break;
  184.     case TOP_TEXT:
  185.     y2 += dy;
  186.     break;
  187.     }
  188. }
  189.  
  190. int GraphicsConsole::cprintf(const char *format,...)
  191. {
  192.     va_list argv;
  193.     int cnt;
  194.     char buf[GC_BUF_SIZE];
  195.  
  196.     va_start(argv,format);
  197.     cnt = vsprintf(buf,format,argv);
  198.     va_end(argv);
  199.     if (cnt)
  200.     cputs(buf);
  201.     return cnt;
  202. }
  203.  
  204. int GraphicsConsole::cputs(const char *str)
  205. {
  206.     int i, j, x, y, x1, y1, x2, y2;
  207.     int bkcolor;
  208.     struct textsettingstype TS;
  209.     struct fillsettingstype FS;
  210.     char buf[GC_BUF_SIZE];
  211.     int ch;
  212.  
  213.     if (!str)
  214.     return 0;
  215.     x = getx(); y = gety();
  216.     gettextsettings(&TS);
  217.     if (ClearTextBk)  {
  218.     getfillsettings(&FS);
  219.     bkcolor = TextBkColor? TextBkColor : getbkcolor();
  220.     }
  221.     setwritemode(OutputWriteMode);
  222.     for (i = j = 0; j >= 0; i++)  {
  223.     switch (str[i])  {
  224.     case '\r':
  225.     case '\n':
  226.         //  fall thru and output buf
  227.     case '\0':
  228.         buf[j] = '\0';
  229.         if (ClearTextBk)  {
  230.         setfillstyle(TextBkPattern,bkcolor);
  231.         TextBox(x,y,buf,TS,x1,y1,x2,y2);
  232.         bar(x1,y1,x2,y2);
  233.         setfillstyle(FS.pattern,FS.color);
  234.         }
  235.         outtextxy(x,y,buf);
  236.         if (TS.direction == HORIZ_DIR)
  237.         switch (str[i])  {
  238.         case '\r':
  239.             if (!ColumnLeft &&
  240.             (TS.horiz == LEFT_TEXT))
  241.             x = 0;
  242.             break;
  243.         case '\n':
  244.             y += 1 + textheight(buf);
  245.             break;
  246.         default:
  247.             if (TS.horiz == LEFT_TEXT)
  248.                 x += textwidth(buf);
  249.             break;
  250.         }
  251.         else // TS.direction == VERT_DIR
  252.         switch (str[i])  {
  253.         case '\r':
  254.             if (!ColumnLeft &&
  255.             (TS.vert == BOTTOM_TEXT))
  256.             y = getmaxy();
  257.             break;
  258.         case '\n':
  259.             x += 1+textheight(buf);
  260.             break;
  261.         default:
  262.             if (TS.horiz == BOTTOM_TEXT)
  263.             y -= textwidth(buf);
  264.             break;
  265.         }
  266.         moveto(x,y);
  267.         j = (str[i])? 0 : -1;// terminate when ready
  268.         break;
  269.     default:
  270.         if (j < GC_BUF_SIZE - 1)
  271.         ch = buf[j++] = str[i];
  272.         break;
  273.     }
  274.     }
  275.     return ch;
  276. }
  277.  
  278. int GraphicsConsole::putch(int c)
  279. {
  280.     char chs[2];
  281.  
  282.     chs[0] = c; chs[1] = '\0';
  283.     return cputs(chs);
  284. }
  285.  
  286. void GraphicsConsole::rubout(int ch)
  287. {
  288.     int x1, y1, x2, y2, lastchX, lastchY;
  289.     struct textsettingstype TS;
  290.     struct fillsettingstype FS;
  291.     char chs[2];
  292.  
  293.     gettextsettings(&TS);
  294.     // Only works for left justified text!
  295.     if (TS.direction == HORIZ_DIR)  {
  296.     if (TS.horiz != LEFT_TEXT)
  297.         return;
  298.     }
  299.     else if (TS.horiz != BOTTOM_TEXT)
  300.     return;
  301.     setwritemode(OutputWriteMode);
  302.     ProportionalBackSpace(lastchX,lastchY,
  303.     getx(),gety(),ch,ch,TS);
  304.     moveto(lastchX,lastchY);
  305.     chs[0] = ch;
  306.     chs[1] = '\0';
  307.     // Only erase XOR_PUT, stroked fonts!
  308.     if ((OutputWriteMode == COPY_PUT) ||
  309.     (TS.font == DEFAULT_FONT))  {
  310.     getfillsettings(&FS);
  311.     if (!TextBkColor)
  312.         setfillstyle(TextBkPattern,getbkcolor());
  313.     else
  314.         setfillstyle(TextBkPattern,TextBkColor);
  315.     TextBox(getx(),gety(),chs,TS,x1,y1,x2,y2);
  316.     bar(x1,y1,x2,y2);
  317.     setfillstyle(FS.pattern,FS.color);
  318.     }
  319.     else  {
  320.     outtextxy(getx(),gety(),chs);
  321.     moveto(lastchX,lastchY);
  322.     }
  323. }
  324.  
  325. int GraphicsConsole::cscanf(const char *format,...)
  326. {
  327.     va_list argv;
  328.     int cnt;
  329.     char buf[GC_BUF_SIZE];
  330.  
  331.     buf[0] = GC_BUF_SIZE - 2;
  332.     cgets(buf);
  333.     va_start(argv,format);
  334.     cnt = vsscanf(&buf[2],format,argv);
  335.     va_end(argv);
  336.     return cnt;
  337. }
  338.  
  339. char * GraphicsConsole::cgets(char *str)
  340. {
  341.     int i, imax, x, y, x1, y1, x2, y2;
  342.     int lastchX, lastchY, nextchX, nextchY;
  343.     struct textsettingstype TS;
  344.     struct fillsettingstype FS;
  345.  
  346.     if (!str)
  347.     return str;
  348.     if ((imax = str[0]) < 2)
  349.     return (char *) 0;
  350.     x = getx(); y = gety();
  351.     gettextsettings(&TS);
  352.     setwritemode(InputWriteMode);
  353.     getfillsettings(&FS);
  354.     if (!TextBkColor)
  355.     setfillstyle(TextBkPattern,getbkcolor());
  356.     else
  357.     setfillstyle(TextBkPattern,TextBkColor);
  358.     InputDone = 0;
  359.     str[i = 2] = '\0';
  360.     while (!InputDone)  {
  361.     // Cursor only for stroked fonts!
  362.     if (CursorChar[0] && (